/*
 *  cstr.hpp - C string wrapper and compare class for hash
 *
 *    Copyright (c) 2001-2006, Luxena Software Company. All rights reserved.
 *
 *  Purpose:
 *
 */

#ifndef __CSTR_HPP__
#define __CSTR_HPP__

#ifndef __cplusplus
#error This header requires a C++ compiler ...
#endif

#include <new>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>


/////////////////////////////////////////////////////////////////////////////
// C string wrapper

class _cstr_t
{
public:
	_cstr_t() { _value = 0; }

	_cstr_t(size_t size) { _value = new char [size]; }

	_cstr_t(const char *value) { set(value); }

	_cstr_t(const _cstr_t& str) { set(str._value); }

	~_cstr_t() { delete [] _value; }

	_cstr_t& operator = (const char *value) {
		delete [] _value;
		set(value);
		return *this;
	}

	_cstr_t& operator = (const _cstr_t& str) { return *this = str._value; }

	operator char * () const { return _value; }

	void attach (char *value) { delete [] _value; _value = value; }

	char * detach () { char *value = _value; _value = 0; return value; }

	static char * trim (char *value)
	{
		char *zero = value;
		while (*value != '\0')
			if (*value++ != ' ') zero = value;
		*zero = '\0';
		return value;
	}
	
	static char * upperCase(char *value)
	{
		char *p = value;
		while (*p != '\0')
			*p++ = toupper(*p);
		return value;
	}

	static char * concat (const char *left, const char *right)
	{
		size_t sizeLeft = left != 0 ? strlen(left) : 0;
		size_t sizeRight = right != 0 ? strlen(right) : 0;
		size_t sizeResult = sizeLeft + sizeRight;
		char *result = new char [sizeResult + 1];
		if (left != 0)
			memcpy(result, left, sizeLeft);
		if (right != 0)
			memcpy(result + sizeLeft, right, sizeRight);
		result[sizeResult] = 0;
		return result;
	}

private:
	void set (const char *value)
	{
		if (value != 0)
		{
			size_t size = strlen(value) + 1;
			_value = new char [size];
			memcpy(_value, value, size);
		}
		else
			_value = 0;
	}

	char *_value;
};


/////////////////////////////////////////////////////////////////////////////
// C string compare class for hash table

class StringComparer
{
public:
	static int Compare(const char *left, const char *right) {
		return strcmp(left, right);
	}

	static unsigned int GetHashCode(const char *key, long tablesize) {
		unsigned int result = 0;
		while (*key != 0)
			result = ((result << 1) ^ tablesize) + *key++;
		return result % tablesize;
	}
};


/////////////////////////////////////////////////////////////////////////////
// Auto C string array cast wrapper

class StringArrayCast {
public:
	StringArrayCast (char **value) {
		_value = const_cast<const char**>(value);
	}
	StringArrayCast (const char **value) {
		_value = value;
	}
	operator char ** () {
		return const_cast<char **>(_value);
	}
	operator const char ** () {
		return _value;
	}
private:
	const char **_value;
};

#endif // __CSTR_HPP__
